using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Xml;
using Graffiti.Core;
using System.Web;
using System.Web.UI;

namespace Graffiti.Slide.Show
{
    /// <summary>
    /// Picasa Slide.Show Photo Gallery
    /// </summary>
    public class PicasaSlideShowPlugin : GraffitiEvent
    {

        #region Properties

        private string _width = "100%";
        public string Width
        {
            get { return _width; }
            set { _width = value; }
        }

        private string _height = "300";
        public string Height
        {
            get { return _height; }
            set { _height = value; }
        }

        private string _picasaUsername = string.Empty;
        public string PicasaUsername
        {
            get { return _picasaUsername; }
            set { _picasaUsername = value; }
        }

        private int _startAlbum = -1;
        public int StartAlbum
        {
            get { return _startAlbum; }
            set { _startAlbum = value; }
        }

        private string _slideTransition = "CrossFadeTransition";
        public string SlideTransition
        {
            get { return _slideTransition; }
            set { _slideTransition = value; }
        }

        private string _postName = string.Empty;
        public string PostName
        {
            get { return _postName; }
            set { _postName = value; }
        }

        private string _modulesXML = string.Empty;
        public string ModulesXML
        {
            get { return _modulesXML; }
            set { _modulesXML = value; }
        }

        #endregion

        #region Constructor
        public PicasaSlideShowPlugin()
        {
            this.ModulesXML = PluginHelper.defaultModulesXML;
        }
        #endregion

        #region Init
        public override void Init(GraffitiApplication ga)
        {
            ga.BeginRequest += new EventHandler(ga_BeginRequest);
            ga.RenderHtmlHeader += new RenderContentEventHandler(ga_RenderHtmlHeader);
            ga.RenderPostBody += new RenderPostBodyEventHandler(ga_RenderPostBody);
        }

        #endregion

        #region GraffitiEvent Properties

        public override bool IsEditable
        {
            get { return true; }
        }

        public override string Name
        {
            get { return "Picasa Slide.Show Photo Gallery"; }
        }

        public override string Description
        {
            get
            {
                return "Adds a photo gallery to a post page using Picasa and the Slide.Show Silverlight component";
            }
        }

        #endregion

        #region Events

        protected void ga_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            HttpContext context = app.Context;
            string path = context.Request.Path.ToLower();

            if (path.Contains("/slideshowplugin-picasa-config.aspx"))
            {
                HandleConfigRequest(context);
                return;
            }
        }

        protected void ga_RenderHtmlHeader(StringBuilder sb, EventArgs e)
        {
            PluginHelper.RenderSlideShowScript(sb, HttpContext.Current.Handler as TemplatedThemePage, PostName);
        }

        protected void ga_RenderPostBody(StringBuilder sb, PostEventArgs e)
        {
            if (e.RenderLocation == PostRenderLocation.Web && e.Post.Name.ToLower() == PostName.ToLower())
            {
                TemplatedThemePage ttp = HttpContext.Current.Handler as TemplatedThemePage;
                string picasaScriptUrl = ttp.ClientScript.GetWebResourceUrl(typeof(Graffiti.Slide.Show.PicasaSlideShowPlugin), "Graffiti.Slide.Show.PicasaDataProvider.js");

                Macros macros = new Macros();
                sb.Append("\n<script type=\"text/javascript\">\n");
                sb.Append("new SlideShow.Control(new SlideShow.XmlConfigProvider({url:\"");
                sb.Append(macros.FullUrl(VirtualPathUtility.ToAbsolute("~/slideshowplugin-picasa-config.aspx")));
                sb.Append("?r=").Append(DateTime.Now.Minute).Append(DateTime.Now.Second);  // Adds some randomness
                sb.Append("&p=").Append(HttpUtility.UrlEncode(picasaScriptUrl));
                sb.Append("\"}));\n");
                sb.Append("</script>\n");
            }
        }

        #endregion

        #region Configuration

        protected override FormElementCollection AddFormElements()
        {
            FormElementCollection fec = new FormElementCollection();

            fec.Add(new MessageElement("intro", "<strong>Picasa Slide.Show Photo Gallery</strong>",
                "Your Picasa Web Album photos will be displayed. <a href=\"http://kevinharder.com/downloads/graffiti/slide-show-plugin/\">Click here</a> for more help &amp; info."));

            fec.Add(new TextFormElement("picasaUserName", "Picasa Username", null));
            PluginHelper.AddOptionFormElements(fec);

            fec.Add(new MessageElement("about", "<br /><strong>About this plugin</strong>",
                "This plugin uses the open source <a href=\"http://www.codeplex.com/SlideShow\">Slide.Show</a> gallery control, which uses <a href=\"http://www.microsoft.com/silverlight/default.aspx\">Microsoft Silverlight 2.0</a> to render. The photos are retrieved from <a href=\"http://picasaweb.google.com\">Picasa Web Albums</a>. Slide.Show Picasa data provider created by <a href=\"http://www.wesleyriley.com\">Wesley Riley</a>. Graffiti plugin written by <a href=\"http://kevinharder.com\">Kevin Harder</a>."));

            return fec;
        }

        protected override NameValueCollection DataAsNameValueCollection()
        {
            NameValueCollection nvc = new NameValueCollection();
            nvc["picasaUserName"] = PicasaUsername;
            nvc["postName"] = PostName;
            nvc["width"] = Width.ToString();
            nvc["height"] = Height.ToString();

            if (StartAlbum < 0)
                nvc["startAlbum"] = string.Empty;
            else
                nvc["startAlbum"] = StartAlbum.ToString();

            nvc["slideTransition"] = SlideTransition;
            nvc["modulesXML"] = ModulesXML;

            return nvc;
        }

        public override StatusType SetValues(System.Web.HttpContext context, NameValueCollection nvc)
        {
            if (string.IsNullOrEmpty(nvc["picasaUserName"]))
            {
                SetMessage(context, "You forgot to enter your Picasa username.");
                return StatusType.Error;
            }
            PicasaUsername = nvc["picasaUserName"];

            Data data = new Data();
            PostName = nvc["postName"];
            Post post = data.GetPost(PostName);
            if (post == null)
            {
                PostName = Util.CleanForUrl(PostName);
                post = data.GetPost(PostName);

                if (post == null)
                {
                    SetMessage(context, "Could not find a post with that post name.");
                    return StatusType.Error;
                }
            }

            try
            {
                if (!string.IsNullOrEmpty(nvc["startAlbum"]))
                    StartAlbum = int.Parse(nvc["startAlbum"]);
                else
                    StartAlbum = -1;
            }
            catch
            {
                StartAlbum = -1;
            }

            Width = nvc["width"];
            Height = nvc["height"];
            SlideTransition = nvc["slideTransition"];
            ModulesXML = nvc["modulesXML"];

            return StatusType.Success;
        }

        #endregion

        #region protected void HandleConfigRequest(HttpContext context)
        protected void HandleConfigRequest(HttpContext context)
        {
            Macros macros = new Macros();
            string picasaScriptUrl = HttpUtility.HtmlEncode(macros.FullUrl(HttpUtility.UrlDecode(context.Request.QueryString["p"])));

            context.Response.Clear();
            context.Response.Cache.SetCacheability(HttpCacheability.Public);

            StringWriter sw = new StringWriter();
            sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
            XmlTextWriter writer = new XmlTextWriter(sw);

            writer.WriteStartElement("configuration");
            writer.WriteAttributeString("width", this.Width);
            writer.WriteAttributeString("height", this.Height);

            writer.WriteStartElement("scripts");
            writer.WriteRaw(string.Format("<script key=\"PicasaDataProvider\" url=\"{0}\" />", picasaScriptUrl));
            writer.WriteEndElement(); // End scripts

            writer.WriteStartElement("modules");
            if (this.ModulesXML.Trim().Length == 0)
                writer.WriteRaw(PluginHelper.defaultModulesXML);
            else
                writer.WriteRaw(this.ModulesXML);
            writer.WriteEndElement(); // End Modules

            writer.WriteStartElement("transitions");
            writer.WriteRaw(PluginHelper.RenderTransition(this.SlideTransition));
            writer.WriteEndElement(); // End Transitions

            writer.WriteStartElement("dataProvider");
            writer.WriteAttributeString("type", "PicasaDataProvider");
            writer.WriteStartElement("option");
            writer.WriteAttributeString("name", "userName");
            writer.WriteAttributeString("value", this.PicasaUsername);
            writer.WriteEndElement(); // End option
            writer.WriteEndElement(); // End dataProvider
            writer.WriteEndElement(); // End configuration

            // save XML into response
            context.Response.ContentEncoding = System.Text.Encoding.UTF8;
            context.Response.ContentType = "text/xml";
            context.Response.Write(sw.ToString());
            context.Response.End();
        }

        #endregion

    }
}
